package com.kate.mall.common.utils;

import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class ListMap2ListVoUtils {
    public static <T> List<T> entity2Vo(List<Map> source, Class<? extends T> targetClazz) {
        //TODO 1.创建从source解析出来的结果集合
        List<T> targetList = new ArrayList();
        //TODO 2.获取目标vo的所有属性对象集合
        Field[] targetFields = targetClazz.getDeclaredFields();
        //TODO 3.暴力破解封装
        Field.setAccessible(targetFields, true);
        try {
            //TODO 4.迭代需要解析的数据源的集合Map元素
            for (Map el : source) {
                //TODO 5.实例化一个目标类对象
                T target = targetClazz.newInstance();
                //TODO 6.迭代目标类的所有属性对象
                for (Field targetField : targetFields) {
                    //TODO 7.根据属性名从源Map集合中获取对应的值
                    Object value = el.get(targetField.getName());
                    //TODO 8.1 如果值为double类型 则需要转换值的为BigDecimal类型
                    //double类型转为BigDecimal
                    if (targetField.getType().equals(BigDecimal.class)) {
                        if (value != null) {
                            //TODO 8.1.1.将转换的值设置到目标对象上
                            targetField.set(target, new BigDecimal(String.valueOf(value)));
                            continue;
                        }
                    }
                    //TODO 8.2 如果isNew、isHot属性类型integer转boolean
                    //isNew、isHot属性类型integer转boolean
                    if (targetField.getName().equals("isNew")) {
                        //TODO 8.2.1.将转换的值设置到目标对象上
                        targetField.set(target, ((Integer) value).equals(new Integer(1)));
                        continue;
                    }

                    //isNew、isHot属性类型integer转boolean
                    if (targetField.getName().equals("isHot")) {
                        targetField.set(target, ((Integer) value).equals(new Integer(1)));
                        continue;
                    }
                    //TODO 8.3.集合数据的填充(暂时没有写到，待优化)
                    if (targetField.getType().equals(List.class)) {
                        continue;
                    }
                    //TODO 8.4.如果isOnSale属性类型integer转boolean  1是上架  0是未上架
                    if (targetField.getName().equals("isOnSale")) {
                        //TODO 8.2.1.将转换的值设置到目标对象上
                        targetField.set(target, ((Integer) value).equals(new Integer(1)) ? true : true);
                        continue;
                    }
                    //TODO 8.4.如果isOnSale属性类型integer转boolean 1是删除 0是未删除
                    if (targetField.getName().equals("deleted")) {
                        //TODO 8.2.1.将转换的值设置到目标对象上
                        targetField.set(target, ((Integer) value).equals(new Integer(1)));
                        continue;
                    }


                    /*
                    源数据：
                    "[\"http://yanxuan.nosdn.127.net/fad166a4742ab3681808c80120eb452a.jpg\",
                    \"http://yanxuan.nosdn.127.net/fad166a4742ab3681808c80120eb452a.jpg\",
                    \"http://yanxuan.nosdn.127.net/fad166a4742ab3681808c80120eb452a.jpg\",
                    \"http://yanxuan.nosdn.127.net/fad166a4742ab3681808c80120eb452a.jpg\",
                     \"http://yanxuan.nosdn.127.net/fad166a4742ab3681808c80120eb452a.jpg\"]"

                    中间工具：hutools
                        ----JsonArray
                        ----JsonArray.parseArray()


                    目标：
                     String[]  garray


                     */
                    //TODO 8.4.商品详情中info数据gallery广告图片，json字符串传字符串数组
                    //TODO 8.4. 商品详情productList中specifications，json字符转字符串数组
                    if (targetField.getName().equals("gallery")||targetField.getName().equals("specifications")) {
                        //TODO 8.2.1.将转换的值设置到目标对象上
                        JSONArray jsonArray = JSONUtil.parseArray(value);
                        targetField.set(target,(String[])jsonArray.toArray(new String[]{}));
                        continue;
                    }

                    //TODO 8.4. 用户信息R(  String )转dto的 LocalDateTime
                    if (targetField.getType().equals(LocalDateTime.class)) {
                        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                        LocalDateTime time = LocalDateTime.parse((String)value, df);
                        //TODO 8.2.1.将转换的值设置到目标对象上
                        targetField.set(target,time);
                        continue;
                    }

                    if (targetField.getType().equals(Date.class)) {
                        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
                        //TODO 8.2.1.将转换的值设置到目标对象上
                        try {
                            targetField.set(target,df.parse((String)value));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        continue;
                    }
                    //TODO 8.5.其他类型的属性值直接设置值到目标对象上
                    targetField.set(target, value);
                }
                //TODO 9.每个初始化好的目标对象放到目标对象结果集合中
                targetList.add(target);
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        //TODO 10.返回结果对象集合
        return targetList;
    }

    public static void main(String[] args) {
        Map m1= new LinkedHashMap();
        m1.put("id",1);
        m1.put("name","kate");
        Map m2= new LinkedHashMap();
        m2.put("id",2);
        m2.put("name","kate2");
        List<Map> source= Arrays.asList(m1,m2);

//        ListFromEntity2VoUtils.entity2Vo(source,CategoryHomeVo.class).forEach(System.out::println);
    }

}
